package com.jp.fm.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.List;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;

import com.jp.fm.dao.TransactionDao;
import com.jp.fm.data.Category;
import com.jp.fm.data.Transaction;

public class SaveTransactions extends ServletParent {

	/**
	 *
	 */
	private static final long serialVersionUID = 1L;

	/**
	 * Constructor of the object.
	 */
	public SaveTransactions() {
		super();
	}

	/**
	 * Destruction of the servlet. <br>
	 */
	public final void destroy() {
		super.destroy(); // Just puts "destroy" string in log
		// Put your code here
	}

	public final void doGet(final HttpServletRequest request,
			final HttpServletResponse response) throws ServletException,
			IOException {

		doPost(request, response);
	}

	public final void doPost(final HttpServletRequest request,
			final HttpServletResponse response) throws ServletException,
			IOException {

		// Lookup accounts and add them to the response.
		int counter = 0;
		String checkComposite = request.getParameter("c");

		if (StringUtils.isNotEmpty(checkComposite)) {
			// This is a composite transaction save

			String ret = "Could not find all params";
			boolean foundError = false;

			Enumeration<String> enumParamNames = request.getParameterNames();
			while (enumParamNames.hasMoreElements()) {
				String paramName = enumParamNames.nextElement();

				if (paramName.startsWith("comp_tran_parent_")) {

					// get the parent transaction ID
					String transactionIdStr = request.getParameter(paramName);
					Transaction parentTrans = getTransactionDao().findById(
							Integer.valueOf(transactionIdStr));

					counter = 0;
					Float compositeTotal = Float
							.valueOf(NumberUtils.FLOAT_ZERO);
					while (true) {
						// Get the child transactions
						String childAmountStr = request
								.getParameter("comp_tran_amt_" + counter);
						if (null == childAmountStr) {
							break;
						}

						String childCategoryStr = request
								.getParameter("comp_tran_category_" + counter);
						Category childCategory = getCategoryDao().findById(
								Integer.valueOf(childCategoryStr));

						String childNoteStr = request
								.getParameter("comp_tran_note_" + counter);

						childNoteStr = URLDecoder.decode(childNoteStr, "UTF-8");

						// Create child transactions
						Transaction childTrans = new Transaction(
								parentTrans.getDate(), null,
								parentTrans.getAccount(),
								Float.valueOf(childAmountStr), childCategory,
								parentTrans.getExternalId(), parentTrans
										.getCategory().getName()
										+ " -> "
										+ childCategory.getName(),
								parentTrans.isConfirmed(), parentTrans.getId());

						childTrans.setNote(childNoteStr);

						parentTrans.getCompositeTransactions().add(childTrans);
						compositeTotal += childTrans.getAmount();
						counter++;
					}

					// Validate the child transactions add up to the parent
					// total
					if (!compositeTotal.equals(parentTrans.getAmount())) {
						foundError = true;
						ret = "Composite total not equal to parent total";
					}

					if (!foundError) {
						// Save the child transactions
						getTransactionDao().writeCompositeTransactions(
								parentTrans);
						ret = "Saved";
					}
					break;
				}
			}

			response.setContentType("text/html");
			PrintWriter out = response.getWriter();
			out.println(ret);
		} else {
			// This is a regular transaction update
			TransactionDao tDao = getTransactionDao();
			while (true) {

				String tranIdStr = request.getParameter("transactionId_"
						+ counter);
				String tranEditStr = request.getParameter("transEditable_"
						+ counter);
				String catStr = request.getParameter("cat_" + counter);

				if (null == tranIdStr) {
					break;
				}

				counter++;

				if (StringUtils.contains(tranEditStr, "false")) {
					continue;
				}

				Transaction tran = tDao.findById(Integer.parseInt(tranIdStr));

				tran.setCategory(getCategoryDao().findById(
						Integer.parseInt(catStr)));

				tran.setConfirmed(true);

				tDao.writeObject(tran);

				// Write child transactions
				List<Transaction> childTrans = tran.getCompositeTransactions();
				for (Transaction transaction : childTrans) {
					transaction.setConfirmed(tran.isConfirmed());
					tDao.writeObject(transaction);
				}
			}

			RequestDispatcher rd = request.getRequestDispatcher("/");
			rd.forward(request, response);
		}
	}
}
